#include "Trait.h"

using namespace std;

/**
 * Constructeur par défaut, initialise le champ Valeur avec un membre
 * de l'énumération.
 *
 * @param trait valeur énumérée que l'on veut assigner.
 */
Trait::Trait(const enumTrait& trait)
  : Valeur( trait )
{}

/**
 * Constructeur qui permet d'initialiser le champ à partir d'un nombre
 * entier.
 *
 * @param trait nombre entier (qui correspond à l'indice du trait) que
 * l'on veut assigner.
 */
Trait::Trait(const unsigned int& trait)
{
  setValeur( trait );
}

/**
 * Le destructeur n'a rien de spécial à faire.
 */
Trait::~Trait()
{}

/**
 * Permet de réaffecter la valeur de Valeur avec un membre de
 * l'énumération.
 *
 * @param trait valeur énumérée que l'on veut assigner.
 */
void Trait::setValeur(const enumTrait& trait)
{
  Valeur = trait;
}

/**
 * Permet de réaffecter la valeur de Valeur avec l'indice du trait
 * voulu dans le tableau des traits d'un personnage.
 *
 * @param trait nombre entier (qui correspond à l'indice du trait) que
 * l'on veut assigner.
 */
void Trait::setValeur(const unsigned int& trait)
{
  if ( trait >= 6 )
    Valeur = Exc;
  else
    Valeur = static_cast< enumTrait >( trait ); 
}

/**
 * Opérateur de sortie, qui permet d'écrire le nom du trait.
 *
 * @param os flot de sortie à utiliser.
 * @param trait Trait que l'on veut écrire.
 *
 * @return une référence sur le flot \c os, modifié.
 */
ostream& operator<<(ostream& os, const Trait& trait)
{
  switch( trait.Valeur )
    {
    case Trait::For:
      return os << "Force";
    case Trait::Dex:
      return os << "Dextérité";
    case Trait::Cons:
      return os << "Constitution";
    case Trait::Int:
      return os << "Intelligence";
    case Trait::Sag:
      return os << "Sagesse";
    case Trait::Char:
      return os << "Charisme";
    case Trait::Exc:
      return os << "Force exceptionnelle";
    default:
      return os;
    }
}

/**
 * Permet de récupérer la valeur de Valeur sous forme d'un nombre
 * entier.
 *
 * @return la valeur de Valeur.
 */
unsigned int Trait::valeur() const
{
  return Valeur;
}

/**
 * Permet d'accéder à la valeur de Valeur sous forme d'un entier, mais
 * cette fois pour être utiliser comme un indice. Cette méthode permet
 * d'écrire :
 * @code
 * vector< unsigned int > vec = ...;
 * Trait force( For );
 *
 * cout << vec[ force ] << endl;
 *
 * @endcode
 *
 * @return la valeur de Valeur.
 */
Trait::operator unsigned int() const
{
  return Valeur;
}
